package me.ivps.android.weibo.ui.maintimeline;

import me.ivps.android.weibo.bean.AccountBean;
import me.ivps.android.weibo.bean.CommentListBean;
import me.ivps.android.weibo.bean.UserBean;
import me.ivps.android.weibo.bean.android.AsyncTaskLoaderResult;
import me.ivps.android.weibo.bean.android.CommentTimeLineData;
import me.ivps.android.weibo.bean.android.TimeLinePosition;
import me.ivps.android.weibo.dao.destroy.DestroyCommentDao;
import me.ivps.android.weibo.support.database.CommentByMeTimeLineDBTask;
import me.ivps.android.weibo.support.error.WeiboException;
import me.ivps.android.weibo.support.lib.MyAsyncTask;
import me.ivps.android.weibo.support.utils.GlobalContext;
import me.ivps.android.weibo.support.utils.Utility;
import me.ivps.android.weibo.ui.actionmenu.CommentFloatingMenu;
import me.ivps.android.weibo.ui.actionmenu.CommentSingleChoiceModeListener;
import me.ivps.android.weibo.ui.adapter.CommentListAdapter;
import me.ivps.android.weibo.ui.basefragment.AbstractTimeLineFragment;
import me.ivps.android.weibo.ui.interfaces.IRemoveItem;
import me.ivps.android.weibo.ui.loader.CommentsByMeDBLoader;
import me.ivps.android.weibo.ui.loader.CommentsByMeMsgLoader;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Toast;

/**
 * User: qii Date: 13-1-22
 */
public class CommentsByMeTimeLineFragment extends
        AbstractTimeLineFragment<CommentListBean> implements IRemoveItem {
    
    private AccountBean accountBean;
    
    private UserBean userBean;
    
    private String token;
    
    private RemoveTask removeTask;
    
    private CommentListBean bean = new CommentListBean();
    
    private TimeLinePosition timeLinePosition;
    
    @Override
    public CommentListBean getList() {
        return bean;
    }
    
    public static CommentsByMeTimeLineFragment getInstance(
            AccountBean accountBean, UserBean userBean, String token) {
        CommentsByMeTimeLineFragment instance = new CommentsByMeTimeLineFragment();
        Bundle args = new Bundle();
        args.putParcelable("accountBean", accountBean);
        args.putParcelable("userBean", userBean);
        args.putString("token", token);
        instance.setArguments(args);
        return instance;
    }
    
    protected void clearAndReplaceValue(CommentListBean value) {
        getList().getItemList().clear();
        getList().getItemList().addAll(value.getItemList());
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        
        outState.putParcelable("account", accountBean);
        outState.putParcelable("userBean", userBean);
        outState.putString("token", token);
        
        if (getActivity().isChangingConfigurations()) {
            outState.putParcelable("bean", bean);
            outState.putSerializable("timeLinePosition", timeLinePosition);
        }
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    
    @Override
    protected void onListViewScrollStop() {
        super.onListViewScrollStop();
        timeLinePosition = Utility
                .getCurrentPositionFromListView(getListView());
    }
    
    @Override
    public void onPause() {
        super.onPause();
        if (!getActivity().isChangingConfigurations()) {
            CommentByMeTimeLineDBTask.asyncUpdatePosition(timeLinePosition,
                    accountBean.getUid());
        }
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        
        switch (getCurrentState(savedInstanceState)) {
            case 0:
                getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null,
                        dbCallback);
                break;
            case 2:
                userBean = (UserBean) savedInstanceState
                        .getParcelable("userBean");
                accountBean = (AccountBean) savedInstanceState
                        .getParcelable("account");
                token = savedInstanceState.getString("token");
                timeLinePosition = (TimeLinePosition) savedInstanceState
                        .getSerializable("timeLinePosition");
                
                Loader<CommentTimeLineData> loader = getLoaderManager()
                        .getLoader(DB_CACHE_LOADER_ID);
                if (loader != null) {
                    getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null,
                            dbCallback);
                }
                
                CommentListBean savedBean = (CommentListBean) savedInstanceState
                        .getParcelable("bean");
                if (savedBean != null && savedBean.getSize() > 0) {
                    clearAndReplaceValue(savedBean);
                    timeLineAdapter.notifyDataSetChanged();
                    refreshLayout(getList());
                    setListViewPositionFromPositionsCache();
                }
                else {
                    getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null,
                            dbCallback);
                }
                break;
        }
    }
    
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
        getListView().setOnItemLongClickListener(onItemLongClickListener);
    }
    
    private AdapterView.OnItemLongClickListener onItemLongClickListener = new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                int position, long id) {
            if (position - 1 < getList().getSize() && position - 1 >= 0) {
                if (actionMode != null) {
                    actionMode.finish();
                    actionMode = null;
                    getListView().setItemChecked(position, true);
                    timeLineAdapter.notifyDataSetChanged();
                    actionMode = getActivity().startActionMode(
                            new CommentSingleChoiceModeListener(getListView(),
                                    timeLineAdapter,
                                    CommentsByMeTimeLineFragment.this,
                                    getList().getItemList().get(position - 1)));
                    return true;
                }
                else {
                    getListView().setItemChecked(position, true);
                    timeLineAdapter.notifyDataSetChanged();
                    actionMode = getActivity().startActionMode(
                            new CommentSingleChoiceModeListener(getListView(),
                                    timeLineAdapter,
                                    CommentsByMeTimeLineFragment.this,
                                    getList().getItemList().get(position - 1)));
                    return true;
                }
            }
            return false;
        }
        
    };
    
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisible() && isVisibleToUser) {
            // ((MainTimeLineActivity) getActivity()).setCurrentFragment(this);
        }
    }
    
    @Override
    public void removeItem(int position) {
        clearActionMode();
        if (removeTask == null
                || removeTask.getStatus() == MyAsyncTask.Status.FINISHED) {
            removeTask = new RemoveTask(GlobalContext.getInstance()
                    .getSpecialToken(), getList().getItemList().get(position)
                    .getId(), position);
            removeTask.executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR);
        }
    }
    
    @Override
    public void removeCancel() {
        clearActionMode();
    }
    
    class RemoveTask extends MyAsyncTask<Void, Void, Boolean> {
        
        String token;
        
        String id;
        
        int positon;
        
        WeiboException e;
        
        public RemoveTask(String token, String id, int positon) {
            this.token = token;
            this.id = id;
            this.positon = positon;
        }
        
        @Override
        protected Boolean doInBackground(Void... params) {
            DestroyCommentDao dao = new DestroyCommentDao(token, id);
            try {
                return dao.destroy();
            }
            catch (WeiboException e) {
                this.e = e;
                cancel(true);
                return false;
            }
        }
        
        @Override
        protected void onCancelled(Boolean aBoolean) {
            super.onCancelled(aBoolean);
            if (Utility.isAllNotNull(getActivity(), this.e)) {
                Toast.makeText(getActivity(), e.getError(), Toast.LENGTH_SHORT)
                        .show();
            }
        }
        
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            if (aBoolean) {
                ((CommentListAdapter) timeLineAdapter).removeItem(positon);
                
            }
        }
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        this.accountBean = getArguments().getParcelable("accountBean");
        this.userBean = getArguments().getParcelable("userBean");
        this.token = getArguments().getString("token");
        
        setRetainInstance(false);
    }
    
    private void setListViewPositionFromPositionsCache() {
        if (timeLinePosition != null) {
            getListView().setSelectionFromTop(timeLinePosition.position + 1,
                    timeLinePosition.top);
        }
        else {
            getListView().setSelectionFromTop(0, 0);
        }
    }
    
    @Override
    protected void buildListAdapter() {
        timeLineAdapter = new CommentListAdapter(this, getList().getItemList(),
                getListView(), true, false);
        pullToRefreshListView.setAdapter(timeLineAdapter);
    }
    
    protected void listViewItemClick(AdapterView parent, View view,
            int position, long id) {
        CommentFloatingMenu menu = CommentFloatingMenu.getInstance(getList()
                .getItem(position));
        menu.show(getFragmentManager(), "");
    }
    
    @Override
    protected void newMsgLoaderSuccessCallback(CommentListBean newValue,
            Bundle loaderArgs) {
        if (newValue != null && newValue.getItemList() != null
                && newValue.getItemList().size() > 0) {
            getList().addNewData(newValue);
            getAdapter().notifyDataSetChanged();
            getListView().setSelectionAfterHeaderView();
            CommentByMeTimeLineDBTask.asyncReplace(getList(),
                    accountBean.getUid());
        }
    }
    
    @Override
    protected void oldMsgLoaderSuccessCallback(CommentListBean newValue) {
        if (newValue != null && newValue.getItemList().size() > 1) {
            getList().addOldData(newValue);
            getAdapter().notifyDataSetChanged();
            CommentByMeTimeLineDBTask.asyncReplace(getList(),
                    accountBean.getUid());
        }
    }
    
    @Override
    protected void middleMsgLoaderSuccessCallback(int position,
            CommentListBean newValue, boolean towardsBottom) {
        
        if (newValue != null) {
            int size = newValue.getSize();
            
            if (getActivity() != null && newValue.getSize() > 0) {
                getList().addMiddleData(position, newValue, towardsBottom);
                
                if (towardsBottom) {
                    getAdapter().notifyDataSetChanged();
                }
                else {
                    
                    View v = Utility.getListViewItemViewFromPosition(
                            getListView(), position + 1 + 1);
                    int top = (v == null) ? 0 : v.getTop();
                    getAdapter().notifyDataSetChanged();
                    int ss = position + 1 + size - 1;
                    getListView().setSelectionFromTop(ss, top);
                }
            }
        }
    }
    
    private LoaderManager.LoaderCallbacks<CommentTimeLineData> dbCallback = new LoaderManager.LoaderCallbacks<CommentTimeLineData>() {
        @Override
        public Loader<CommentTimeLineData> onCreateLoader(int id, Bundle args) {
            getPullToRefreshListView().setVisibility(View.INVISIBLE);
            return new CommentsByMeDBLoader(getActivity(), GlobalContext
                    .getInstance().getCurrentAccountId());
        }
        
        @Override
        public void onLoadFinished(Loader<CommentTimeLineData> loader,
                CommentTimeLineData result) {
            if (result != null) {
                clearAndReplaceValue(result.cmtList);
                timeLinePosition = result.position;
            }
            
            getPullToRefreshListView().setVisibility(View.VISIBLE);
            getAdapter().notifyDataSetChanged();
            setListViewPositionFromPositionsCache();
            
            refreshLayout(getList());
            /**
             * when this account first open app,if he don't have any data in
             * database,fetch data from server automally
             */
            if (getList().getSize() == 0) {
                getPullToRefreshListView().setRefreshing();
                loadNewMsg();
            }
            
            getLoaderManager().destroyLoader(loader.getId());
            
        }
        
        @Override
        public void onLoaderReset(Loader<CommentTimeLineData> loader) {
            
        }
    };
    
    protected Loader<AsyncTaskLoaderResult<CommentListBean>> onCreateNewMsgLoader(
            int id, Bundle args) {
        String accountId = accountBean.getUid();
        String token = accountBean.getAccess_token();
        String sinceId = null;
        if (getList().getItemList().size() > 0) {
            sinceId = getList().getItemList().get(0).getId();
        }
        return new CommentsByMeMsgLoader(getActivity(), accountId, token,
                sinceId, null);
    }
    
    protected Loader<AsyncTaskLoaderResult<CommentListBean>> onCreateMiddleMsgLoader(
            int id, Bundle args, String middleBeginId, String middleEndId,
            String middleEndTag, int middlePosition) {
        String accountId = accountBean.getUid();
        String token = accountBean.getAccess_token();
        return new CommentsByMeMsgLoader(getActivity(), accountId, token,
                middleBeginId, middleEndId);
    }
    
    protected Loader<AsyncTaskLoaderResult<CommentListBean>> onCreateOldMsgLoader(
            int id, Bundle args) {
        String accountId = accountBean.getUid();
        String token = accountBean.getAccess_token();
        String maxId = null;
        if (getList().getItemList().size() > 0) {
            maxId = getList().getItemList()
                    .get(getList().getItemList().size() - 1).getId();
        }
        return new CommentsByMeMsgLoader(getActivity(), accountId, token, null,
                maxId);
    }
}
